-
Notifications
You must be signed in to change notification settings - Fork 2
/
Rename.c
138 lines (101 loc) · 4.17 KB
/
Rename.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*++
toro C Library
https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library
Copyright (c) 2017-2024, Kilian Kegel. All rights reserved.
SPDX-License-Identifier: GNU General Public License v3.0
Module Name:
Rename.c
Abstract:
Implementation of the Standard C function.
Rename a file or directory.
Author:
Kilian Kegel
--*/
#include <CdeServices.h>
extern void* __cdeGetAppIf(void);
extern int _strnicmp(const char* pszDst, const char* pszSrc, size_t count);
extern int swprintf(wchar_t* pszDest, size_t dwCount, const wchar_t* pszFormat, ...);
extern size_t strlen(const char* pszBuffer);
extern char* strrchr(const char* str, int c);
extern void* malloc(size_t size);
extern void free(void* ptr);
static char* chkpath(const char* pOld, const char* pNew); // prototype
/*++
Synopsis
#include <stdio.h>
int rename(const char *old, const char *new);
Description
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/rename-wrename?view=msvc-160&viewFallbackFrom=vs-2019
The rename function causes the file whose name is the string pointed to by old to be
henceforth known by the name given by the string pointed to by new. The file named
old is no longer accessible by that name. If a file named by the string pointed to by new
exists prior to the call to the rename function, the behavior is implementation-defined.
Returns
The rename function returns zero if the operation succeeds, nonzero if it fails in
which case if the file existed previously it is still known by its original name.
*/
int rename(const char* pszOld, const char* pszNew) {
CDE_APP_IF* pCdeAppIf = __cdeGetAppIf();
int nRet = 0;
do {
if (NULL == pszOld || NULL == pszNew)
break;
if (NULL != chkpath(pszOld, pszNew)) { // check, if criterias are matched, e.g.: renaming inside the same directory
size_t oldsize = sizeof(wchar_t) * (1 + strlen(pszOld));
size_t newsize = sizeof(wchar_t) * (1 + strlen(pszNew));
wchar_t* pwcsOld = malloc(oldsize);
wchar_t* pwcsNew = malloc(newsize);
swprintf(pwcsOld, oldsize, L"%S", pszOld);
swprintf(pwcsNew, newsize, L"%S", pszNew);
nRet = pCdeAppIf->pCdeServices->pFrename(pCdeAppIf, pwcsOld, pwcsNew);
{
nRet = nRet == 1 ? 0 : -1; // 0 == noerror, -1 == error
}
free(pwcsOld);
free(pwcsNew);
}
} while (0);
return nRet;
}
static char* chkpath(const char* pOld, const char* pNew) {
/*++
Routine Description:
This function checks, if the both given pathnames + filenames matches the criterias:
1. if pathnames are given, they must be equal
2. that means, renaming is only allowed in the same directory
3. the Windows MoveFile() is used but inter-directory moves/renames are blocked in this implementation
Arguments:
@param[in] const char *pOld
@param[in] const char *pNew
Return Value:
@retval on SUCCESS: pointer to new file name w/o path
@retval on FAILURE: NULL
*/
size_t size;
char* pStrold, * pStrnew, * pRet = NULL;
int equ;
//
// check for a given path, if path, then equal path on both sides!!! Caseinsensitive
//
do {
pStrold = strrchr(pOld, '\\'); // search for backslash
pStrnew = strrchr(pNew, '\\'); // search for backslash
if (NULL == pStrold) { // if no path for the old file...
if (NULL != pStrnew) // ... there can not be a path for the new file
break; // break and return NULL if this in not true
pRet = ++pStrnew;
}
else { // path for old available and required for the new one too...
if (NULL == pStrnew) { // path missing, but required
break;
}
else {
size = 1 + pStrold - pOld;
equ = !_strnicmp(pOld, pNew, size);
if (equ)
pRet = ++pStrnew;
}
}
} while (0);
return pRet;
}